package edu.hcmus.sow.web.user;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import edu.hcmus.sow.domain.Group;
import edu.hcmus.sow.service.UserService;
import edu.hcmus.sow.utils.SecurityUtil;

@Controller
public class GroupController {
   // ~ Instance fields
   // ================================================================================================
   @Autowired
   private UserService userService;

   // ~ Methods
   // ================================================================================================
   @RequestMapping(value = "/admin/groups")
   public String listGroups() {
      return "admin/groups";
   }

   @RequestMapping("/admin/group/search")
   @ResponseBody
   public List<Map<String, String>> search() {
      Integer clientID = SecurityUtil.getCurrentClient();

      List<Map<String, String>> result = new ArrayList<Map<String, String>>();
      List<Group> groups = userService.getGroups(clientID);

      for (Group g : groups) {
         Map<String, String> map = new HashMap<String, String>();
         map.put("id", g.getId().toString());
         map.put("name", g.getName());
         map.put("description", g.getDescription());
         map.put("createdDate", DateFormatUtils.format(g.getCreatedDate(), "MM/dd/yyyy HH:mm:ss"));
         map.put("createdBy", g.getUserByCreatedBy().getUsername());
         result.add(map);
      }

      return result;
   }

   @RequestMapping("/ajax/admin/group")
   public ModelAndView displayGroup(@RequestParam(value = "id", required = false) Integer id) {
      GroupForm groupForm = new GroupForm();
      if (id != null) {
         Group group = userService.getGroupByID(id);
         groupForm.setId(id);
         groupForm.setName(group.getName());
         groupForm.setDescription(group.getDescription());
      }

      ModelAndView mav = new ModelAndView();
      mav.addObject("groupForm", groupForm);
      mav.setViewName("controls/group_form");
      return mav;
   }

   @RequestMapping(value = "/ajax/admin/group/save", method = RequestMethod.POST)
   public ModelAndView saveGroup(@Valid GroupForm groupForm, BindingResult result) {
      validateGroup(groupForm, result);

      if (!result.hasErrors()) {
         Group group = userService.saveGroup(groupForm.getId(), groupForm.getName(), groupForm.getDescription());

         groupForm.setId(group.getId());
      }

      ModelAndView mav = new ModelAndView();
      mav.addObject("groupForm", groupForm);
      mav.addObject("hasErrors", result.hasErrors());
      mav.setViewName("controls/group_form");
      return mav;
   }

   @RequestMapping(value = "/ajax/admin/group/delete", method = RequestMethod.POST)
   @ResponseBody
   public String deleteGroup(@RequestParam(value = "id", required = true) Integer id) {
      if (userService.deleteGroup(id))
         return "success";
      return "error";
   }

   private void validateGroup(GroupForm groupForm, Errors errors) {
      if (!errors.hasFieldErrors("name")) {
         List<Group> groups = userService.findGroupByName(SecurityUtil.getCurrentClient(), groupForm.getName());
         int groupId = groupForm.getId() == null ? -1 : groupForm.getId().intValue();
         if (groups.size() > 0 && groups.get(0).getId().intValue() != groupId) {
            errors.rejectValue("name", "err.name", "Group name already exists.");
         }
      }
   }
}
